﻿using Opc.Ua;
using Opc.Ua.Client;
using SHRIS.MIS.Common.Util.Extension;
using SHRIS.MIS.Entity.ScadaBaseInfo;
using SHRIS.MIS.Entity.ScadaData;
using SHRIS.MIS.Service.OpcService;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SHRIS.MIS.Service.Device
{
    public class WashMachine_01 : BasicDevice
    {
        private readonly IEnumerable<OpcDataSourceEntity> _opcDataSourceEntities;

        public WashMachine_01(DeviceEntity deviceEntity,
            WorkshopCommunicationService workshopCommunicationService,
            IEnumerable<OpcDataSourceEntity> opcDataSourceEntities)
            : base(deviceEntity, workshopCommunicationService)
        {
            _opcDataSourceEntities = opcDataSourceEntities;
            CheckOutDataType();
        }


        private void CheckOutDataType()
        {
            //对所有OPC 数据类型进行校验，如果不对记入LOG

        }

        public override void InitalDevice()
        {
            //创建opc 订阅

            //找出该通道下的订阅数据，dataAction==4 为订阅
            var subscriptionDatas = _opcDataSourceEntities.Where(i => i.DataAction == 4);

            //找出订阅数据的服务器列表
            var serverIds = subscriptionDatas.Select(i => i.ServerId).Distinct().ToList();

            if (serverIds.Count() == 1)
            {
                _workshopCommunicationService.CreateOpcSubscription(subscriptionDatas, DataHandler);
            }


            //用deviceCode作为订阅组名字
            //var subscriptionName = _deviceEntity.DeviceCode;

        }

        private void DataHandler(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
        {
            try
            {
                MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
                //Console.WriteLine(notification.Value.StatusCode.ToString());

                if (notification != null)
                {
                    Guid dataId = new Guid();
                    bool isId = Guid.TryParse(monitoredItem.DisplayName, out dataId);
                    if (isId && (!dataId.IsGuidNullOrEmpty()))
                    {
                        var dataSource = _opcDataSourceEntities.Where(i => i.Id == dataId).First();
                        switch (dataSource.DataName)
                        {
                            case "BypassStatus":
                                {
                                    BypassStatus = (bool)notification.Value.Value;
                                    break;
                                }
                            case "EMO":
                                {
                                    EMO = (bool)notification.Value.Value;
                                    break;
                                }
                            case "Ready":
                                {
                                    Ready = (bool)notification.Value.Value;
                                    break;
                                }
                            case "End":
                                {
                                    End = (bool)notification.Value.Value;
                                    break;
                                }
                            case "WorkpieceSource":
                                {
                                    WorkpieceSource = (short)notification.Value.Value;
                                    break;
                                }
                            case "MCode":
                                {
                                    if (notification.Value.Value != null)
                                    {
                                        MCode = notification.Value.Value.ToString();
                                    }
                                    break;
                                }
                            case "MStatus":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    MStatus = new BitArray(b);
                                    break;
                                }
                            case "MAlarm1":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    MAlarm1 = new BitArray(b);
                                    break;
                                }
                            case "MAlarm2":
                                {
                                    ushort _value = (ushort)notification.Value.Value;
                                    byte[] b = BitConverter.GetBytes(_value);
                                    MAlarm2 = new BitArray(b);
                                    break;
                                }
                            case "WashTime":
                                {
                                    WashTime = long.Parse(notification.Value.Value.ToString());
                                    break;
                                }
                            case "WashSpeed":
                                {
                                    WashSpeed = double.Parse(notification.Value.Value.ToString());
                                    break;
                                }
                            case "CleanEquStartEquTime":
                                {
                                    if (notification.Value.Value != null)
                                    {
                                        CleanEquStartEquTime = DateTimeOffset.Parse(notification.Value.Value.ToString());
                                    }
                                    break;
                                }
                            case "CleanEquRunningTime":
                                {
                                    if (notification.Value.Value != null)
                                    {
                                        CleanEquRunningTime = Double.Parse(notification.Value.Value.ToString());
                                    }
                                    break;
                                }
                            case "HasAlarm":
                                {
                                    HasAlarm = (bool)notification.Value.Value;
                                    break;
                                }
                            case "HasError":
                                {
                                    HasError = (bool)notification.Value.Value;
                                    break;
                                }
                            default:
                                {
                                    break;
                                }
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #region 设备参数

        private bool hasAlarm;
        /// <summary>
        /// 存在报警
        /// </summary>
        public bool HasAlarm
        {
            get
            {
                return hasAlarm;
            }
            set
            {
                bool previewVlaue = hasAlarm;
                hasAlarm = value;
                OnPropertyChanged("HasAlarm", previewVlaue, hasAlarm);
            }
        }

        private bool hasError;
        /// <summary>
        /// 存在错误
        /// </summary>
        public bool HasError
        {
            get
            {
                return hasError;
            }
            set
            {
                bool previewVlaue = hasError;
                hasError = value;
                OnPropertyChanged("HasError", previewVlaue, hasError);
            }
        }


        private DateTimeOffset cleanEquStartEquTime;
        /// <summary>
        /// 清洗设备本次开机时刻
        /// DB7.DBB784
        /// </summary>
        public DateTimeOffset CleanEquStartEquTime
        {
            get
            {
                return cleanEquStartEquTime;
            }
            set
            {
                DateTimeOffset previewVlaue = cleanEquStartEquTime;
                cleanEquStartEquTime = value;
                OnPropertyChanged("CleanEquStartEquTime", previewVlaue, cleanEquStartEquTime);
            }
        }

        private double cleanEquRunningTime;
        /// <summary>
        /// 清洗设备开机时间，永不清零（单位:小时）
        /// DB7.DBD792
        /// </summary>
        public double CleanEquRunningTime
        {
            get
            {
                return cleanEquRunningTime;
            }
            set
            {
                double previewVlaue = cleanEquRunningTime;
                cleanEquRunningTime = value;
                OnPropertyChanged("CleanEquRunningTime", previewVlaue, cleanEquRunningTime);
            }
        }

        private bool bypassStatus;
        /// <summary>
        /// 孔深测量Bypass
        /// </summary>
        public bool BypassStatus
        {
            get
            {
                return bypassStatus;
            }
            set
            {
                bool previewVlaue = bypassStatus;
                bypassStatus = value;
                OnPropertyChanged("BypassStatus", previewVlaue, bypassStatus);
            }
        }

        private bool eMO;
        /// <summary>
        /// 急停
        /// </summary>
        public bool EMO
        {
            get
            {
                return eMO;
            }
            set
            {
                bool previewVlaue = eMO;
                eMO = value;
                OnPropertyChanged("EMO", previewVlaue, eMO);
            }
        }

        private bool ready;
        /// <summary>
        /// 准备
        /// </summary>
        public bool Ready
        {
            get
            {
                return ready;
            }
            set
            {
                bool previewVlaue = ready;
                ready = value;
                OnPropertyChanged("Ready", previewVlaue, ready);
            }
        }

        private bool end;
        /// <summary>
        /// 结束
        /// </summary>
        public bool End
        {
            get
            {
                return end;
            }
            set
            {
                bool previewVlaue = end;
                end = value;
                OnPropertyChanged("End", previewVlaue, end);
            }
        }

        private short workpieceSource;
        /// <summary>
        /// 工件来源
        /// </summary>
        public short WorkpieceSource
        {
            get
            {
                return workpieceSource;
            }
            set
            {
                short previewVlaue = workpieceSource;
                workpieceSource = value;
                OnPropertyChanged("WorkpieceSource", previewVlaue, workpieceSource);
            }
        }

        private string mCode;
        public string MCode
        {
            get
            {
                return mCode;
            }
            set
            {
                string previewVlaue = mCode;
                mCode = value;
                OnPropertyChanged("MCode", previewVlaue, mCode);
            }
        }

        private BitArray mStatus;
        public BitArray MStatus
        {
            get
            {
                return mStatus;
            }
            set
            {
                BitArray previewVlaue = mStatus;
                mStatus = value;
                OnPropertyChanged("MStatus", previewVlaue, mStatus);
            }
        }

        private BitArray mAlarm1;
        public BitArray MAlarm1
        {
            get
            {
                return mAlarm1;
            }
            set
            {
                BitArray previewVlaue = mAlarm1;
                mAlarm1 = value;
                OnPropertyChanged("MAlarm1", previewVlaue, mAlarm1);
            }
        }

        private BitArray mAlarm2;
        public BitArray MAlarm2
        {
            get
            {
                return mAlarm2;
            }
            set
            {
                BitArray previewVlaue = mAlarm2;
                mAlarm2= value;
                OnPropertyChanged("MAlarm2", previewVlaue, mAlarm2);
            }
        }

        private long washTime;
        public long WashTime
        {
            get
            {
                return washTime;
            }
            set
            {
                long previewVlaue = washTime;
                washTime = value/(1000*60);
                OnPropertyChanged("WashTime", previewVlaue, washTime);
            }
        }

        private double washSpeed;
        public double WashSpeed
        {
            get
            {
                return washSpeed;
            }
            set
            {
                double previewVlaue = washSpeed;
                washSpeed = value;
                OnPropertyChanged("WashSpeed", previewVlaue, washSpeed);
            }
        }

        #endregion
    }
}
